﻿using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework.Graphics;
using Daybreak.Core.Rendering.Pipeline;

namespace Daybreak.Core.Rendering.Materials
{
    public class BasicShader : Shader
    {
        BasicEffect basicEffect;

        public BasicShader()
        {
            Init();
        }

        private void Init()
        {
            basicEffect = new BasicEffect(Engine.GraphicsDevice, null);

            _effect = basicEffect;

            basicEffect.EnableDefaultLighting();
            basicEffect.LightingEnabled = true;
            //basicEffect.PreferPerPixelLighting = false;
            basicEffect.DirectionalLight1.Enabled = false;
            basicEffect.DirectionalLight2.Enabled = false;

            // material properties (we do not need to connect them to scene objects)

            // per material parameters
            EffectParameter basicTextureParam = basicEffect.Parameters["BasicTexture"];
            AddTexture(basicTextureParam, SasSemantic.diffuse);

            EffectParameter fogEnabledParam = basicEffect.Parameters["FogEnabled"];
            AddMaterialAttribute(fogEnabledParam, SasSemantic.none, new Shader.BoolValue());
            
            EffectParameter fogStartParam = basicEffect.Parameters["FogStart"];
            AddFloat(fogStartParam, SasSemantic.none);
            
            EffectParameter fogEndParam = basicEffect.Parameters["FogEnd"];
            AddFloat(fogEndParam, SasSemantic.none);
            
            EffectParameter fogColorParam = basicEffect.Parameters["FogColor"];
            AddColor(fogColorParam, SasSemantic.none);
            
            EffectParameter diffuseColorParam = basicEffect.Parameters["DiffuseColor"];
            AddColor(diffuseColorParam, SasSemantic.diffuse);

            EffectParameter specularColorParam = basicEffect.Parameters["SpecularColor"];
            AddColor(specularColorParam, SasSemantic.specular);
            
            EffectParameter emissiveColorParam = basicEffect.Parameters["EmissiveColor"];
            AddColor(emissiveColorParam, SasSemantic.emissive);
            
            EffectParameter specularPowerParam = basicEffect.Parameters["SpecularPower"];
            AddFloat(specularPowerParam, SasSemantic.specularpower);
            
            EffectParameter alphaParam = basicEffect.Parameters["Alpha"];
            AddFloat(alphaParam, SasSemantic.opacity);

            // connected properties
            
            // per object parameters
            EffectParameter worldParam = basicEffect.Parameters["World"];

            // per object attributes
            AddObjectAttribute(worldParam, SasSemantic.world);

            // per frame parameters
            EffectParameter viewParam = basicEffect.Parameters["View"];
            EffectParameter projectionParam = basicEffect.Parameters["Projection"];
            EffectParameter ambientLightColorParam = basicEffect.Parameters["AmbientLightColor"];
            EffectParameter eyePositionParam = basicEffect.Parameters["EyePosition"];
            EffectParameter lightDirParam = basicEffect.Parameters["DirLight0Direction"];
            EffectParameter lightDiffColorParam = basicEffect.Parameters["DirLight0DiffuseColor"];
            EffectParameter lightSpecColorParam = basicEffect.Parameters["DirLight0SpecularColor"];

            // per frame attributes
            AddFrameAttribute(ambientLightColorParam, SasSemantic.ambient, SceneObject.AmbientLight);
            AddFrameAttribute(eyePositionParam, SasSemantic.cameraposition, SceneObject.Any);
            AddFrameAttribute(lightDirParam, SasSemantic.direction, SceneObject.DirectionalLight);
            AddFrameAttribute(lightDiffColorParam, SasSemantic.diffuse, SceneObject.DirectionalLight);
            AddFrameAttribute(lightSpecColorParam, SasSemantic.specular, SceneObject.DirectionalLight);
            AddFrameAttribute(viewParam, SasSemantic.view, SceneObject.Any);
            AddFrameAttribute(projectionParam, SasSemantic.projection, SceneObject.Any);

        }

        public override bool UseTangents 
        {
            get { return false; }  
        }


        internal BasicEffect BasicEffect
        {
            get { return basicEffect; }
        }

    }
}
